package main

import (
	"fmt"
	"net/http"
	"os"
	"strings"
	"time"
)

func retrunHeader(w http.ResponseWriter, r *http.Request) {
	// 返回请求header到响应header当中
	for k, v := range r.Header {
		w.Header().Set(k, strings.Join(v, ""))
	}
	// 设置header需要在设置状态码和写body之前，否则后面添加的header无效
	// for k, v := range r.Header {
	// 	// w.Header().Set(k, strings.Join(v, ""))
	// 	// fmt.Println(k, v)

	// 	fmt.Fprintln(w, k, v)
	// }
	// w.WriteHeader(500)
}

func getIPandPort(r string) (IPVersion string, IPAddr string, srcPort string) {
	// ipv6 [fc00::1:100]:44610  ipv4 172.30.30.5:37336
	if strings.Index(r, ".") == -1 {
		IPVersion = "ipv6"

	} else {
		IPVersion = "ipv4"
	}
	list := strings.Split(r, ":")
	srcPort = list[len(list)-1]
	IPAddr = strings.Join(list[0:len(list)-1], ":")
	return
}

func printSimpleLog(IPAddr string, httpStatusCode int, httpURL string) {
	fmt.Printf("[%v] Client IP %v access %v, the http status code is %v.\n", time.Now().Format("2006-01-02T15:04:05-0700"), IPAddr, httpURL, httpStatusCode)
}

func getEnv(i string) string {
	return os.Getenv(i)
}

// 4.当访问 localhost/healthz 时，应返回200, 如果不是localhost返回403拒绝服务
func healthCheck(w http.ResponseWriter, r *http.Request) {
	if _, IPAddr, _ := getIPandPort(r.RemoteAddr); IPAddr == "127.0.0.1" || IPAddr == "[::1]" {
		w.WriteHeader(200)
	} else {
		w.WriteHeader(403)
	}
}

func home(w http.ResponseWriter, r *http.Request) {
	//1.接收客户端 request，并将 request 中带的 header 写入 response header
	retrunHeader(w, r)

	// 2.读取当前系统的环境变量中的 VERSION 配置，并写入 response header
	w.Header().Set("VERSION", getEnv("VERSION")) // header无论大小写都会转换成首字母为大写

	_, IPAddr, _ := getIPandPort(r.RemoteAddr)
	httpStatusCode := 200
	w.WriteHeader(httpStatusCode)
	// 3.Server 端记录访问日志包括客户端 IP，HTTP 返回码，输出到 server 端的标准输出, 增加访问的URL路径部分和时间输出，时间格式使用nginx time_iso8601格式"1970-09-28T12:00:00+06:00"
	printSimpleLog(IPAddr, httpStatusCode, r.RequestURI)

}

func main() {
	http.HandleFunc("/", home)
	http.HandleFunc("/healthz", healthCheck)
	err := http.ListenAndServe(":80", nil)

	if err != nil {
		fmt.Printf("http server failed to start, err:%v\n", err)
		return
	}
}
